From 641915974be5113ab3bb16e1b5aa0be274d66608 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jonas=20=C3=85dahl?= Date: Fri, 20 Nov 2020 16:56:36 +0100 Subject: [PATCH] gdk/toplevel: Make gdk_toplevel_present() async The plan is to concencrate size computations as part of the frame clock dispatch, meaning we shouldn't do it synchronously in the present() function. Still, in Wayland, and maybe elsewhere, it is done in the present() function, e.g. when no state change was made, but this will eventually be changed. --- gdk/broadway/gdksurface-broadway.c | 4 +- gdk/gdktoplevel.c | 16 ++--- gdk/gdktoplevel.h | 2 +- gdk/gdktoplevelprivate.h | 2 +- gdk/wayland/gdksurface-wayland.c | 106 ++++++++++++++++------------- gdk/x11/gdksurface-x11.c | 6 +- 6 files changed, 69 insertions(+), 67 deletions(-) diff --git a/gdk/broadway/gdksurface-broadway.c b/gdk/broadway/gdksurface-broadway.c index d9e45ad077..bc5f3eb6c9 100644 --- a/gdk/broadway/gdksurface-broadway.c +++ b/gdk/broadway/gdksurface-broadway.c @@ -1524,7 +1524,7 @@ show_surface (GdkSurface *surface) gdk_surface_invalidate_rect (surface, NULL); } -static gboolean +static void gdk_broadway_toplevel_present (GdkToplevel *toplevel, GdkToplevelLayout *layout) { @@ -1583,8 +1583,6 @@ gdk_broadway_toplevel_present (GdkToplevel *toplevel, gdk_broadway_surface_unmaximize (surface); show_surface (surface); - - return TRUE; } static gboolean diff --git a/gdk/gdktoplevel.c b/gdk/gdktoplevel.c index 34328db10d..4cff2bb3dd 100644 --- a/gdk/gdktoplevel.c +++ b/gdk/gdktoplevel.c @@ -51,11 +51,10 @@ enum static guint signals[N_SIGNALS] = { 0 }; -static gboolean +static void gdk_toplevel_default_present (GdkToplevel *toplevel, GdkToplevelLayout *layout) { - return FALSE; } static gboolean @@ -239,18 +238,17 @@ gdk_toplevel_install_properties (GObjectClass *object_class, * compute the preferred size of the toplevel surface. See * #GdkToplevel::compute-size for details. * - * Presenting may fail. - * - * Returns: %FALSE if @toplevel failed to be presented, otherwise %TRUE. + * Presenting is asynchronous and the specified layout parameters are not + * guaranteed to be respected. */ -gboolean +void gdk_toplevel_present (GdkToplevel *toplevel, GdkToplevelLayout *layout) { - g_return_val_if_fail (GDK_IS_TOPLEVEL (toplevel), FALSE); - g_return_val_if_fail (layout != NULL, FALSE); + g_return_if_fail (GDK_IS_TOPLEVEL (toplevel)); + g_return_if_fail (layout != NULL); - return GDK_TOPLEVEL_GET_IFACE (toplevel)->present (toplevel, layout); + GDK_TOPLEVEL_GET_IFACE (toplevel)->present (toplevel, layout); } /** diff --git a/gdk/gdktoplevel.h b/gdk/gdktoplevel.h index 05fafa4b5f..28402feb10 100644 --- a/gdk/gdktoplevel.h +++ b/gdk/gdktoplevel.h @@ -129,7 +129,7 @@ GDK_AVAILABLE_IN_ALL G_DECLARE_INTERFACE (GdkToplevel, gdk_toplevel, GDK, TOPLEVEL, GObject) GDK_AVAILABLE_IN_ALL -gboolean gdk_toplevel_present (GdkToplevel *toplevel, +void gdk_toplevel_present (GdkToplevel *toplevel, GdkToplevelLayout *layout); GDK_AVAILABLE_IN_ALL diff --git a/gdk/gdktoplevelprivate.h b/gdk/gdktoplevelprivate.h index 989ac29c46..52dcdca0ad 100644 --- a/gdk/gdktoplevelprivate.h +++ b/gdk/gdktoplevelprivate.h @@ -13,7 +13,7 @@ struct _GdkToplevelInterface { GTypeInterface g_iface; - gboolean (* present) (GdkToplevel *toplevel, + void (* present) (GdkToplevel *toplevel, GdkToplevelLayout *layout); gboolean (* minimize) (GdkToplevel *toplevel); gboolean (* lower) (GdkToplevel *toplevel); diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c index 1c6c27c1c0..27eb433a58 100644 --- a/gdk/wayland/gdksurface-wayland.c +++ b/gdk/wayland/gdksurface-wayland.c @@ -4756,79 +4756,87 @@ gdk_wayland_toplevel_class_init (GdkWaylandToplevelClass *class) gdk_toplevel_install_properties (object_class, 1); } -static void -reconfigure_callback (void *data, - struct wl_callback *callback, - uint32_t time) +static gboolean +did_maximize_layout_change (GdkToplevel *toplevel, + GdkToplevelLayout *layout) { - gboolean *done = (gboolean *) data; + GdkSurface *surface = GDK_SURFACE (toplevel); + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - *done = TRUE; -} + if (!impl->toplevel.layout) + return TRUE; -static const struct wl_callback_listener reconfigure_listener = { - reconfigure_callback -}; + if (gdk_toplevel_layout_get_maximized (impl->toplevel.layout) != + gdk_toplevel_layout_get_maximized (layout)) + return TRUE; + + return FALSE; +} static gboolean +did_fullscreen_layout_change (GdkToplevel *toplevel, + GdkToplevelLayout *layout) +{ + GdkSurface *surface = GDK_SURFACE (toplevel); + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + + if (!impl->toplevel.layout) + return TRUE; + + if (gdk_toplevel_layout_get_fullscreen (impl->toplevel.layout) != + gdk_toplevel_layout_get_fullscreen (layout)) + return TRUE; + + if (gdk_toplevel_layout_get_fullscreen_monitor (impl->toplevel.layout) != + gdk_toplevel_layout_get_fullscreen_monitor (layout)) + return TRUE; + + return FALSE; +} + +static void gdk_wayland_toplevel_present (GdkToplevel *toplevel, GdkToplevelLayout *layout) { GdkSurface *surface = GDK_SURFACE (toplevel); GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - GdkWaylandDisplay *display_wayland; - struct wl_callback *callback; - gboolean done = FALSE; - int last_configure_serial = impl->last_configure_serial; - gboolean needs_reconfigure = TRUE; + gboolean pending_configure = FALSE; - if (gdk_toplevel_layout_get_maximized (layout)) - { - gdk_wayland_surface_maximize (surface); - needs_reconfigure = FALSE; - } - else + if (did_maximize_layout_change (toplevel, layout)) { - gdk_wayland_surface_unmaximize (surface); + if (gdk_toplevel_layout_get_maximized (layout)) + gdk_wayland_surface_maximize (surface); + else + gdk_wayland_surface_unmaximize (surface); + pending_configure = TRUE; } - if (gdk_toplevel_layout_get_fullscreen (layout)) + if (did_fullscreen_layout_change (toplevel, layout)) { - GdkMonitor *monitor = gdk_toplevel_layout_get_fullscreen_monitor (layout); - if (monitor) - gdk_wayland_surface_fullscreen_on_monitor (surface, monitor); + if (gdk_toplevel_layout_get_fullscreen (layout)) + { + GdkMonitor *monitor; + + monitor = gdk_toplevel_layout_get_fullscreen_monitor (layout); + if (monitor) + gdk_wayland_surface_fullscreen_on_monitor (surface, monitor); + else + gdk_wayland_surface_fullscreen (surface); + } else - gdk_wayland_surface_fullscreen (surface); - needs_reconfigure = FALSE; + { + gdk_wayland_surface_unfullscreen (surface); + } + pending_configure = TRUE; } - else - gdk_wayland_surface_unfullscreen (surface); g_clear_pointer (&impl->toplevel.layout, gdk_toplevel_layout_unref); impl->toplevel.layout = gdk_toplevel_layout_copy (layout); gdk_wayland_surface_show (surface, FALSE); - display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); - callback = wl_display_sync (display_wayland->wl_display); - wl_proxy_set_queue ((struct wl_proxy *) callback, impl->event_queue); - wl_callback_add_listener (callback, - &reconfigure_listener, - &done); - while (is_realized_toplevel (impl) && - (!impl->initial_configure_received || !done)) - wl_display_dispatch_queue (display_wayland->wl_display, impl->event_queue); - - wl_callback_destroy (callback); - - if (needs_reconfigure && - last_configure_serial == impl->last_configure_serial && - !(surface->state & (GDK_TOPLEVEL_STATE_MAXIMIZED | - GDK_TOPLEVEL_STATE_FULLSCREEN | - GDK_TOPLEVEL_STATE_TILED))) + if (!pending_configure) configure_surface_geometry (surface); - - return TRUE; } static gboolean diff --git a/gdk/x11/gdksurface-x11.c b/gdk/x11/gdksurface-x11.c index 24b536cb96..c4b14e11e3 100644 --- a/gdk/x11/gdksurface-x11.c +++ b/gdk/x11/gdksurface-x11.c @@ -4849,7 +4849,7 @@ gdk_x11_toplevel_class_init (GdkX11ToplevelClass *class) gdk_toplevel_install_properties (object_class, LAST_PROP); } -static gboolean +static void gdk_x11_toplevel_present (GdkToplevel *toplevel, GdkToplevelLayout *layout) { @@ -4922,7 +4922,7 @@ gdk_x11_toplevel_present (GdkToplevel *toplevel, gdk_x11_surface_unfullscreen (surface); if (surface->destroyed) - return TRUE; + return; was_mapped = GDK_SURFACE_IS_MAPPED (surface); @@ -4933,8 +4933,6 @@ gdk_x11_toplevel_present (GdkToplevel *toplevel, if (!was_mapped) gdk_surface_invalidate_rect (surface, NULL); - - return TRUE; } static gboolean -- 2.30.2